package com.yz.web.api;

import lombok.extern.slf4j.Slf4j;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;


@Slf4j
@ControllerAdvice
public class ApiResponseBodyAdvice implements ResponseBodyAdvice<Object> {

    @Override
    public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {

//        Class<?> containingClass = returnType.getContainingClass();
//        Class<?> declaringClass = returnType.getDeclaringClass();
//        Annotation[] methodAnnotations = returnType.getMethodAnnotations();
        boolean wrapAnnInClass = returnType.getContainingClass().isAnnotationPresent(ApiController.class);
        boolean withContaining = returnType.getDeclaringClass().isAnnotationPresent(ApiController.class);
        boolean wrapAnnInMethod = returnType.hasMethodAnnotation(ApiController.class);
        boolean notWrapAnnInMethod = returnType.hasMethodAnnotation(NotWrapResponse.class);
        return (wrapAnnInMethod || wrapAnnInClass) && !notWrapAnnInMethod;
    }

    @Override
    public Object beforeBodyWrite(Object body,
                                  MethodParameter returnType,
                                  MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType,
                                  ServerHttpRequest request,
                                  ServerHttpResponse response) {

        String requestMethod = request.getMethodValue();
        String scheme = request.getURI().getScheme();
        String host = request.getURI().getHost();
        int port = request.getURI().getPort();
        String path = request.getURI().getPath();
        String query = request.getURI().getRawQuery();
        String targetUrl = requestMethod + " " + scheme + "://" + host + ":" + port + path;
        log.debug(targetUrl);
        if (query != null) {
            log.debug(query);
        }
        if (body == null) {
            return new ResponseWrapper<>(targetUrl);
        }

        //匹配ResponseResult
        if (body instanceof ResponseWrapper) {
            ((ResponseWrapper) body).setTargetUrl(targetUrl);
            return body;
        }

        ResponseWrapper<Object> responseWrapper = new ResponseWrapper<>();
        responseWrapper.setTargetUrl(targetUrl);
        responseWrapper.setData(body);
        responseWrapper.setSuccess(true);

        return responseWrapper;
    }
}

